/*
验证给定值是否合格的方法，用于校验表单
 验证方法使用：
        在main.js中引入，使用Vue.use()注册方法，然后在每个vue组件中就会含有this.$validation方法
        $validation方法的参数，为一个对象或一个数组，
        传入对象时为一个验证
        传入数组时为多个验证，数组的每一项是一个对象
        每个验证对象的定义：
        rule，字符串，验证规则，必须为ruleObj对象中的键名
        value，要验证的值
        tip，字符串，验证失败时的提示语，可不传，没传时使用默认的提示语
        args，单个值或数组，额外传入的参数，具体的参数顺序需查看验证方法
        ref,字符串，可不传，用于记录表单的位置的字符串，用于focus聚焦效果
*/

//前处理
function preHandle(data) {
    if (!data) {
        data = '';
    }
    data = data.toString();
    data = data.replace(/\s/g, '');
    return data;
}

var ruleObj = {
    //姓名校验(required默认为true必传，required为false意为姓名可以为空)
    NAME(data, required = true, prefix = '') {
        // var flag = true;
        // var tip = '';
        // data = preHandle(data);
        // if (!required && !data) {
        //     tip = '';
        //     flag = true;
        // } else(required && !data) {
        //         tip = prefix + '未输入姓名';
        //         flag = false;
        //     }
        // else {
        //     var re = /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$/;
        //     if (!re.test(data)) {
        //         tip = prefix + '输入有误,长度需在2-20个字以内';
        //         flag = false;
        //     }
        // }
        // const obj = {
        //     flag: flag,
        //     tip: tip,
        // };
        return { flag: true };
    },
    CUSTNAME(data, required = true) {
        var flag = true;
    var tip = '';
    data = preHandle(data);
    if (!required && !data) {
      tip = '';
      flag = true;
    } else if (required && !data) {
      tip = '请输入姓名';
      flag = false;
    } else {
      var re = /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,30}$/;
      if (!re.test(data)) {
        tip = '姓名格式不正确';
        flag = false;
      }
    }
    const obj = {
      flag: flag,
      tip: tip,
    };
    return obj;
    },

    //校验民族
    NATION(data, required = true) {
        var flag = true;
        var tip = '';
        data = preHandle(data);
        if (!required && !data) {
            tip = '';
            flag = true;
        } else if (required && !data) {
            tip = '请输入民族';
            flag = false;
        } else {
            var re = /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{1,20}$/;
            if (!re.test(data)) {
                tip = '民族名称格式不正确';
                flag = false;
            }
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    //手机号码校验
    MOBILE(data, required = true) {
        let flag = true;
        let tip = '';
        data = preHandle(data);
        if (!required && !data) {
            tip = '';
            flag = true;
        } else if (required && !data) {
            tip = '请输入手机号码';
            flag = false;
        } else {
            let re = /^1\d{10}$/;
            if (!re.test(data)) {
                tip = '手机号码格式不正确';
                flag = false;
            }
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },

    //电话号码正则表达式（支持手机号码，3-4位区号，7-8位直播号码，1－4位分机号）
    PHONE(data) {
        // let flag = true;
        // let tip = '';
        // data = preHandle(data);
        // if (!data) {
        //     tip = '';
        //     flag = true;
        // } else {
        //     // var reg01 = /^(0|86|17951)?(13[0-9]|15[012356789]|17[01678]|18[0-9]|14[57])[0-9]{8}$/;
        //     // var reg02 = /^(0[0-9]{2,3}\-)([2-9][0-9]{6,7})+(\-[0-9]{1,4})?$/;
        //     var reg = /(^(0[0-9]{2,3}\-)?([2-9][0-9]{6,7})+(\-[0-9]{1,4})?$)|(^((\(\d{3}\))|(\d{3}\-))?(1[3578]\d{9})$)|(^(400)-(\d{3})-(\d{4})(.)(\d{1,4})$)|(^(400)-(\d{3})-(\d{4}$))/;
        //     if (!reg.test(data)) {
        //         tip = '电话号码格式不正确';
        //         flag = false;
        //     }
        // }
        // const obj = {
        //     flag: flag,
        //     tip: tip,
        // };
        return { flag: true };
    },

    //图形验证码
    IMGCODE(data) {
        let flag = true;
        let tip = '';
        data = preHandle(data);
        if (!data) {
            tip = '请输入图形验证码';
            flag = false;
        } else {
            let re = /^[A-Za-z0-9]{4}$/;
            if (!re.test(data)) {
                tip = '图形验证码格式不正确';
                flag = false;
            }
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    //短信验证码
    SMSCODE(data) {
        let flag = true;
        let tip = '';
        data = preHandle(data);
        if (!data) {
            tip = '请输入短信验证码';
            flag = false;
        } else {
            let re = /^[0-9]{6}$/;
            if (!re.test(data)) {
                tip = '短信验证码格式不正确';
                flag = false;
            }
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    //邮政编码
    ZIPCODE(data, required = true) {
        let flag = true;
        let tip = '';
        data = preHandle(data);
        if (!required && !data) {
            tip = '';
            flag = true;
        } else if (required && !data) {
            tip = '请输入邮政编码';
            flag = false;
        } else {
            let re = /^[0-9]\d{5}(?!\d)$/;
            if (!re.test(data)) {
                tip = '邮政编码格式不正确';
                flag = false;
            }
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    //输入不能有特殊字符
    COMMON(data) {
        let flag = true;
        let tip = '';
        data = preHandle(data);
        let re = /[@#\$%\^&\*]+/g;
        if (re.test(data)) {
            tip = '不能有特殊字符';
            flag = false;
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },

    //身份证有效期限格式校验,过期校验，
    // 参数date,年份4位，月份2位，日期2位，1985.12.15-2020.08.15
    // exclude，数组，哪些不校验,soon快要过期不校验
    IDDATE(date, exclude = []) {
        date = preHandle(date);
        var reg_validity = /^\d{4}\.\d{2}\.\d{2}-\d{4}\.\d{2}\.\d{2}$/g;
        let flag = true;
        let tip = '';
        if (date === '') {
            tip = '请输入身份证有效期';
            flag = false;
        } else if (!reg_validity.test(date)) {
            tip = '身份证有效期限格式不正确';
            flag = false;
        } else {
            var endTimeArr = date.split('-')[1].split('.');
            var year = Number(endTimeArr[0]);
            var month = Number(endTimeArr[1]);
            var day = Number(endTimeArr[2]);

            var endTimeVal = new Date(year, month - 1, day).getTime();
            var nowTimeVal = new Date().getTime();
            var monthTimeVal = endTimeVal - 1000 * 60 * 60 * 24 * 30; //过期一个月前的时间

            if (month == 0 || month > 12 || day > 31) {
                tip = '身份证有效期限格式不正确';
                flag = false;
            } else if (month == 2 && day > 29) {
                tip = '身份证有效期限格式不正确';
                flag = false;
            } else if (nowTimeVal <= endTimeVal && nowTimeVal >= monthTimeVal) {
                if (!exclude.includes('soon')) {
                    flag = false;
                    tip = '您的身份证有效期小于30天';
                }
            } else if (nowTimeVal > endTimeVal) {
                flag = false;
                tip = '您的身份证已过期';
            }
        }
        return {
            flag,
            tip,
        };
    },

    // 身份证号码校验
    IDNUM(code, required = true) {
        var city = {
            11: '北京',
            12: '天津',
            13: '河北',
            14: '山西',
            15: '内蒙古',
            21: '辽宁',
            22: '吉林',
            23: '黑龙江 ',
            31: '上海',
            32: '江苏',
            33: '浙江',
            34: '安徽',
            35: '福建',
            36: '江西',
            37: '山东',
            41: '河南',
            42: '湖北 ',
            43: '湖南',
            44: '广东',
            45: '广西',
            46: '海南',
            50: '重庆',
            51: '四川',
            52: '贵州',
            53: '云南',
            54: '西藏 ',
            61: '陕西',
            62: '甘肃',
            63: '青海',
            64: '宁夏',
            65: '新疆',
            71: '台湾',
            81: '香港',
            82: '澳门',
            91: '国外 ',
        };
        var tip = '';
        var flag = true;
        code = preHandle(code);
        if (!required && !code) {
            tip = '';
            flag = true;
        } else if (required && !code) {
            tip = '请输入身份证号码';
            flag = false;
        }

        //验证身份证格式（6个地区编码，8位出生日期，3位顺序号，1位校验位）
        else if (!/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
                code
            )) {
            tip = '身份证号格式错误';
            flag = false;
        } else if (!city[code.substr(0, 2)]) {
            tip = '身份证号地址 格式错误';
            flag = false;
        } else {
            console.log('校验证件号====', code);
            //18位身份证需要验证最后一位校验位
            if (code.length == 18) {
                code = code.split('');
                //∑(ai×Wi)(mod 11)
                //加权因子
                var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
                //校验位
                var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
                var sum = 0;
                var ai = 0;
                var wi = 0;
                for (var i = 0; i < 17; i++) {
                    ai = code[i];
                    wi = factor[i];
                    sum += ai * wi;
                }
                var last = parity[sum % 11];
                if (last != code[17]) {
                    tip = '身份证校验位错误';
                    flag = false;
                }
            }
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    // 必填验证
    EMPTY(value) {
        var flag = true;
        var tip = '';
        value = preHandle(value);
        if (value == '') {
            tip = '值不能为空';
            flag = false;
        } else {
            flag = true;
        }
        return {
            tip,
            flag,
        };
    },
    /*
输入内容长度验证,
length,最大长度字节数
includeSpaces，是否将空格计入长度，默认计算空格
 */
    LENGTH(value, length = 40, includeSpaces = true) {
        var flag = true;
        var tip = '';
        let temp = 0;
        value = preHandle(value);
        for (var i = 0; i < value.length; i++) {
            if (/[^\x00-\xff]/.test(value[i])) {
                temp += 2;
            } else if (/^[0-9a-zA-Z]+$/.test(value[i])) {
                temp += 1;
            } else if (/\s/.test(value[i])) {
                if (includeSpaces) {
                    temp += 1;
                }
            } else {
                temp += 1;
            }
        }
        if (temp > length) {
            flag = false;
            tip = '字符串长度过长';
        }
        return {
            flag,
            tip,
        };
    },
    // 浮点数字校验,positive默认为false浮点数可以为正负，positive为true只能为正数
    FLOAT(data, positive = false, required = true) {
        let flag = true;
        let tip = '';
        data = preHandle(data);
        if (!required && !data) {
            tip = '';
            flag = true;
        } else if (required && !data) {
            tip = '请输入数值';
            flag = false;
        } else {
            let re = positive ? /^\d+\.?\d*$/g : /^-?\d+\.?\d*$/g;
            if (!re.test(data)) {
                tip = '输入内容不是数值';
                flag = false;
            }
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    // 汉字校验
    // 传入正则
    REG(value, reg) {
        var flag = true;
        var tip = '';
        value = preHandle(value);
        if (!reg.test(value)) {
            tip = '所传值格式不正确';
            flag = false;
        } else {
            flag = true;
        }
        return {
            tip,
            flag,
        };
    },
    // 校验省市区填写完整
    AREA(val) {
        val = preHandle(val);
        var flag = true;
        var tip = '';
        const a = areaList.province_list[val];
        const b = areaList.city_list[val];
        if (b) {
            flag = false;
            tip = '请选择区';
        } else if (a) {
            flag = false;
            tip = '请选择市';
        } else if (!val) {
            flag = false;
            tip = '请选择省';
        }
        return {
            tip,
            flag,
        };
    },
    // 邮箱
    EMAIL(data) {
        var flag = true;
        var tip = '';
        data = preHandle(data);
        var re = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
        if (data != '' && !re.test(data)) {
            tip = '邮箱格式不正确';
            flag = false;
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    // 统一社会信用代码
    MERCHANTCODE(data,required = true) {
        var flag = true;
        var tip = '';
        data = preHandle(data);
        if (!required && !data) {
            tip = '';
            flag = true;
        }else if (data != '' && data.length != 18) {
            tip = '统一社会信用代码格式不正确';
            flag = false;
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },

    // 非负整数包含0
    POSITIVEINT(data) {
        var flag = true;
        var tip = '';
        data = preHandle(data);
        var re = /^\d+$/;
        if (data != '' && !re.test(data)) {
            tip = '格式不正确';
            flag = false;
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
    // 非负浮点数包含0
    POSITIVEFLOAT(data) {
        var flag = true;
        var tip = '';
        data = preHandle(data);
        var re = /^\d+(\.\d+)?$/;
        if (data != '' && !re.test(data)) {
            tip = '格式不正确';
            flag = false;
        }
        const obj = {
            flag: flag,
            tip: tip,
        };
        return obj;
    },
     // 日期2不能小于等于日期1,open为true时，日期2可以等于日期1
  DATERANGE(date1, date2, open = false,format) {
    // 手机端使用new Date('2023-3-12').getTime()会得到NaN
    function transfer(date) {
      return date.split('-').join('/');
    }
    let time1;
    let time2;
    if(format){
     time1= new Date(transformValue(date1,format)).getTime();
     time2= new Date(transformValue(date2,format)).getTime();
    }else{
       time1 = new Date(transfer(date1)).getTime();
       time2 = new Date(transfer(date2)).getTime();
    }
    var flag = true;
    var tip = '';

    if (!date1) {
      flag = false;
      tip = '开始日期未填';
    } else if (isNaN(time1)) {
      flag = false;
      tip = '开始日期格式不正确';
    } else if (!date2) {
      flag = false;
      tip = '终止日期未填';
    } else if (isNaN(time2)) {
      flag = false;
      tip = '终止日期格式不正确';
    } else if (time1 > time2) {
      flag = false;
      tip = '终止日期需大于开始日期';
    } else if (time1 == time2) {
      if (!open) {
        flag = false;
        tip = '终止日期需大于开始日期';
      }
    }
    return {
      flag: flag,
      tip: tip,
    };
  },
};
/*
validation方法的参数，为一个对象或一个数组，
传入对象时为一个验证
传入数组时为多个验证，数组的每一项是一个对象
每个验证对象的定义：
rule，字符串，验证规则，必须为ruleObj对象中的键名
value，字符串，要验证的值
tip，字符串，自定义的提示语，没传时使用默认的提示语
args，单个值或数组，额外传入的参数
ref,字符串，用于记录表单的位置的字符串
condition,校验条件，当condition为false时不执行此条校验，为true时才执行此条校验，默认true
*/
export function validation(testArr) {
    if (Object.prototype.toString.call(testArr) == '[object Object]') {
        testArr = [testArr];
    }
    let flag = true;
    let tip = '';
    let ref = '';
    for (let i = 0; i < testArr.length; i++) {
        const item = testArr[i];
        if (!item.rule) {
            console.warn('请传入验证函数');
            flag = false;
            tip = '未传入验证函数';
            break;
        }
        var testFunc;
        if (typeof item.rule === 'function') {
            testFunc = item.rule;
        } else {
            const ruleName = item.rule.toLocaleUpperCase();
            testFunc = ruleObj[ruleName];
        }

        const value = item.value;
        let args = item.args;
        if (args === undefined) {
            args = [];
        } else if (!Array.isArray(args)) {
            args = [args];
        }
        let condition = true;
        if (item.condition !== undefined) {
          condition = item.condition;
        }
        if (condition) {
            if (testFunc) {
                const res = testFunc(value, ...args);
                if (res.flag === false) {
                    flag = false;
                    tip = item.tip ? item.tip : res.tip;
                    ref = item.ref ? item.ref : '';
                    break;
                }
            } else {
                console.warn('验证函数' + ruleName + '不存在！');
                flag = false;
                tip = '验证函数' + ruleName + '不存在！';
                break;
            }
        }
    }
    return {
        flag,
        tip,
        ref,
    };
}

export default {
    install(vue) {
        vue.mixin({
            created: function() {
                this.$validation = validation;
            },
        });
    },
};